/*
 *  This file is part of Bracket Properties
 *  Copyright 2011 David R. Smith
 *
 */

package asia.redact.bracket.properties;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Map.Entry;
import java.util.Set;

/**
 * Output the properties to various data sinks and in various formats.
 * 
 * @author Dave
 *
 */
public class OutputAdapter {

	final Properties properties;
	final static String lineSeparator = System.getProperty("line.separator");

	public OutputAdapter(Properties properties) {
		super();
		this.properties = properties;
	}
	
	public void writeTo(File file){
		writeTo(file,new BasicOutputFormat());
	}
	
	public void writeTo(File file, OutputFormat format) {
		FileWriter out = null;
		try {
			out = new FileWriter(file);
			writeTo(out, format);
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if(out != null) {
				try {
					out.close();
				} catch (IOException e) {}
			}
		}
	}
	
	public void writeTo(Writer writer, OutputFormat format) throws IOException {
		Set<Entry<String,ValueModel>> set = properties.getPropertyMap().entrySet();
		
		writer.append(format.formatHeader());
		
		for(Entry<String,ValueModel> e: set) {
			String key = e.getKey();
			ValueModel model = e.getValue();
			writer.append(lineSeparator);
			writer.append(format.format(key, model));
		}
		
		writer.append(format.formatFooter());
	}
	
	public void writeTo(Writer writer) throws IOException {
		Set<Entry<String,ValueModel>> set = properties.getPropertyMap().entrySet();
		OutputFormat format = new BasicOutputFormat();
		
		writer.append(format.formatHeader());
		
		for(Entry<String,ValueModel> e: set) {
			String key = e.getKey();
			ValueModel model = e.getValue();
		//	writer.append(System.lineSeparator());
			writer.append(format.format(key, model));
		}
		
		writer.append(format.formatFooter());
	}
	
	public void writeAsXml(final Writer out){
		try {
			out.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
			out.append(lineSeparator);
		} catch (IOException e) {
			e.printStackTrace();
		}
		GroupParams params = new GroupParams();
		// change the root node name
		params.rootNodeName = "properties";
		Node node = properties.getTree(params);
		visit(node, 0, new GenerateXMLNodeVisitor(out));
	}
	
	private void visit(Node node, int level, NodeVisitor func){
		
		func.setLevel(level);
		func.pre(node);
		func.action(node);  
		level++;
		
	    for(Node childNode:node.getChildren()){
	        visit(childNode, level, func);
	    }
	    
	    func.post(node);
	    
	}
	
}
